package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.dto.CourseBaseDTO;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.api.content.system.model.dto.CourseCategoryDTO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.enums.content.CourseModeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.JsonUtil;
import com.xuecheng.content.agent.SystemApiAgent;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.common.constant.CoursePubTemplateKey;
import com.xuecheng.content.convert.CoursePubConvert;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.entity.CoursePub;
import com.xuecheng.content.entity.CourseTeacher;
import com.xuecheng.content.mapper.CoursePubMapper;
import com.xuecheng.content.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author itcast
 */

@Slf4j
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {
    @Autowired
    private CourseBaseService courseBaseService;

    @Autowired
    private CourseMarketService courseMarketService;

    @Autowired
    private TeachplanService teachplanService;

    @Autowired
    private SystemApiAgent systemApiAgent;

    @Autowired
    private CourseTeacherService courseTeacherService;
    /*

     * 主方法业务：
     * 1.构建CoursePub数据并保存
     *
     * 2.根据CoursePub内容构架DataMap数据
     *
     * 3.将DataMap进行返回
     * */
    @Override
    public Map<String, Object> previewCourse(Long courseId, Long companyId) {
        //1.构建CoursePub数据并保存
        CoursePub coursePub = generateCoursePub(courseId,companyId);

    //    2.根据CoursePub内容构架DataMap数据
        Map<String, Object> stringObjectMap = generateDataMap(coursePub);


        return stringObjectMap;
    }
    private Map<String, Object> generateDataMap(CoursePub coursePub) {

        // 1.构建数据模型对象
        HashMap<String, Object> dataMap = new HashMap<>();

        // 2.构建coursePub
        dataMap.put(CoursePubTemplateKey.COURSEPUB, coursePub);

        // 3.构建courseMarket
        String marketJsonString = coursePub.getMarket();
        CourseMarket courseMarket = JsonUtil.jsonToObject(marketJsonString, CourseMarket.class);

        dataMap.put(CoursePubTemplateKey.COURSEMARKET,courseMarket );

        // 4.构建课程计划
        String teachplanJsonString = coursePub.getTeachplan();
        TeachplanDTO teachplanDTO = JsonUtil.jsonToObject(teachplanJsonString, TeachplanDTO.class);
        dataMap.put(CoursePubTemplateKey.TEACHPLANNODE,teachplanDTO );

        // 5.构建课程模式
        CourseModeEnum[] values = CourseModeEnum.values();
        dataMap.put(CoursePubTemplateKey.COURSETEACHMODEENUMS,values );

        return dataMap;
    }
    /*
     * 构建CoursePub数据并保存
     *   业务分析：
     *       1.判断关键数据
     *        courseId companyId
     *       2.判断业务数据
     *           课程基础信息
     *               判断是否存在
     *               判断是否是同一家机构
     *               判断是否删除
     *               判断审核状态：教学机构课程预览--未提交、审核未通过
     *           课程营销
     *               判断是否存在：根据courseid
     *           课程计划
     *               获得课程计划：根据courseId和companyId（树形结构）
     *           课程教师
     *               判断教师信息是否存在：一定要确保课程最少有一个教师信息
     *
     *           课程分类数据并完善Coursepub数据
     *               调用system服务获得课程分类的名称
     *
     *       3.保存课程发布数据
     *           CoursePub数据保存数据库中
     *               课程基础信息  课程营销  课程计划  课程教师
     *
     *       4.将coursePub数据返回
     *
     * */
    public CoursePub generateCoursePub(Long courseId, Long companyId) {
        CourseBaseDTO courseBaseDTO= courseBaseService.getCourseBaseById(courseId, companyId);
        String auditStatus = courseBaseDTO.getAuditStatus();
        if (CourseAuditEnum.AUDIT_PASTED_STATUS.equals(auditStatus)
                //判断课程审核状态
                ||CourseAuditEnum.AUDIT_COMMIT_STATUS.equals(auditStatus)||
                CourseAuditEnum.AUDIT_PUBLISHED_STATUS.equals(auditStatus)) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        // 课程营销
        //判断是否存在 根据courseid
        LambdaQueryWrapper<CourseMarket> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CourseMarket::getCourseId, courseId);
        CourseMarket courseMarket = courseMarketService.getOne(lambdaQueryWrapper);
        if (ObjectUtils.isEmpty(courseMarket)) {
            ExceptionCast.cast(ContentErrorCode.E_120101);
        }
        //获取课程计划
        //  获得课程计划；根据courseId 和 companyId
        TeachplanDTO teachplanDTO = teachplanService.queryTreeNodes(courseId, companyId);
        //课程教师
        //判断教师信息是否存在  确保至少有一个教师
//        if (ObjectUtils.isEmpty(courseTeacherService.queryTeacherById(courseId,companyId))) {
//            ExceptionCast.cast(ContentErrorCode.E_1200503);
//        }
        LambdaQueryWrapper<CourseTeacher> courseTeacherLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseTeacherLambdaQueryWrapper.eq(CourseTeacher::getCourseId, courseId);
        List<CourseTeacher> teachers = courseTeacherService.list(courseTeacherLambdaQueryWrapper);
        //     课程分类数据并完善Coursepub数据
        //         调用system服务获得课程分类的名称
        String mt = courseBaseDTO.getMt();//小分类
        String st = courseBaseDTO.getSt();//大分类
        RestResponse<CourseCategoryDTO> byId = systemApiAgent.getById(mt);
        if (! (byId.isSuccessful())) {
            ExceptionCast.castWithCodeAndDesc(byId.getCode(),byId.getMsg());
        }
        RestResponse<CourseCategoryDTO> byId1 = systemApiAgent.getById(st);
        if (!(byId1.isSuccessful())) {
            ExceptionCast.castWithCodeAndDesc(byId1.getCode(),byId1.getMsg());
        }
        CourseCategoryDTO mte = byId.getResult();
        CourseCategoryDTO ste = byId1.getResult();
        //构建coursePub数据并保存操作
        //课程基础数据
        CoursePub coursePub = CoursePubConvert.INSTANCE.courseBase2coursePub(courseBaseDTO);
        //课程营销数据
        String marketJsonString = JsonUtil.objectTojson(courseMarket);
        coursePub.setMarket(marketJsonString);
        coursePub.setPrice(courseMarket.getPrice());
        coursePub.setCharge(courseMarket.getCharge());
        //课程计划数据
        String teachplanJsonString = JsonUtil.objectTojson(teachplanDTO);
        coursePub.setTeachplan(teachplanJsonString);
        //课程教师（json）
        String teachersJsonString = JsonUtil.objectTojson(teachers);
        coursePub.setTeachers(teachersJsonString);
        //课程分类数据
        coursePub.setMtName(mte.getName());
        coursePub.setStName(ste.getName());
        // 3.保存课程发布数据
        //     CoursePub数据保存数据库中
        //         课程基础信息  课程营销  课程计划  课程教师
        // 一个courseBase数据对应一个coursePub数据
        LambdaQueryWrapper<CoursePub> coursePubLambdaQueryWrapper = new LambdaQueryWrapper<>();
        coursePubLambdaQueryWrapper.eq(CoursePub::getCourseId, courseId);
        coursePubLambdaQueryWrapper.eq(CoursePub::getCompanyId, companyId);
        CoursePub one = this.getOne(coursePubLambdaQueryWrapper);
        boolean result = false;
        //判断发布数据是否存在
        if (ObjectUtils.isEmpty(one)) {

            //     如果不存在
            //             创建课程发布数据
            //     创建课程发布数据时，要将coursePub和courseBase数据进行关联
            coursePub.setCourseId(courseBaseDTO.getCourseBaseId());
            result = this.save(coursePub);
        } else {
            //     如果存在
            //             修改课程发布数据内容
            coursePub.setId(one.getId());

            result = this.updateById(coursePub);
        }
        if (!result) {
            ExceptionCast.cast(ContentErrorCode.E_120005);
        }

        return coursePub;
    }
}
